
//  standard C headers

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/mman.h>
#include <math.h>
#include <getopt.h>
#include <time.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/shm.h>
#include <pthread.h>
#include <sys/time.h>

#ifndef _SCHMIDT_CAM_H_
#define _SCHMIDT_CAM_H_

//  User defined headers
#include "COMMON.h"
#include "REG_BITS.h"

#include "ADS5294.h"
#include "AD9508.h"
#include "DACx0508.h"
#include "ADG714.h"
#include "SPI.h"
#include "SPI_PS.h"
#include "Float_SPI_PS.h"
#include "MISC.h"
#include "BONN_SHUTTER.h"
#include "ADC2REG_CLK.h"

#include "Daisy.h"

#include "float2bin.h"

//  Ini parser
#include "dictionary.h"
#include "iniparser.h"

#include "CCD290_DRV_Config.h"	// added @2022-12-11 by XYH

#include "ReadOut.h"

typedef struct _pthread_data {
    struct sockaddr_in  client_addr;
    int                 sock_fd;            //  socket hander
    int                 *socket_cnt;        //  指向全局变量，保存/更新socket连接数
    pthread_t           *tid_exposure;      //  保存曝光线程的id 
    int                 *abort_exposure;    //  指向全局变量，控制是否终止曝光
} pthread_data;


void *serveForClient(void * arg);

void startExposure(void *arg);

void abortExposure(void *arg);

#define REG_NUM CCD290_DRV_CONFIG_PARAM_NUM

typedef struct _SchmidtCAM_Config{

    AD9508_Config       *config_ad9508;

    ADC2REG_CLK_CONFIG  *config_adc2reg_clk;

    ADS5294_Config      *config_ads5294;

    ccd290_drive_config *config_ccd_drive;

    DAISY_Config        *config_daisy;

    // add config_daisy_vod_10V and config_daisy_vod_29V to lower and restore VOD (added@20240427)
    // DAISY_Config        *config_daisy_vod_10V;
    // DAISY_Config        *config_daisy_vod_29V;

    DACx0508_Config     *config_dacx0508;

    char dcds_config_file[1024];    // 记录DCDS参数配置文件
    char log_path[1024];            // path of the log files
    char log_shutter_fname[1024];   // filename of shutter status
    char log_camera_fname[1024];    // filename of CCD  status

    uint32_t n_row;
    uint32_t n_col;
    int n_bytes;        // 图像保存至DDR时，每个像元占的字节数

    uint32_t *gpio_flt_ctrl;
    uint32_t *gpio_flt_data;

    uint32_t *gpio_in;
    uint32_t *gpio_pl_ps;

    uint32_t *gpio_out;
    uint32_t *gpio_out2;

    uint32_t *gpio_spi_ps_ctrl;
    uint32_t *gpio_spi_ps_data;

    // Socket and thread
    // pthread_data *pdata;    // added@2023-12-23

} SchmidtCAM_Config;


int init_SchmidtCAM_Config( SchmidtCAM_Config *cfg, char *config_path );
int free_SchmidtCAM_Config( SchmidtCAM_Config *cfg );

int socket_power_up(    SchmidtCAM_Config *cfg, 
                        uint32_t *gpio_flt_ctrl, 
                        uint32_t *gpio_flt_data,
                        uint32_t *gpio_in,
                        uint32_t *gpio_pl_ps,
                        uint32_t *gpio_out,
                        uint32_t *gpio_out2,
                        uint32_t *gpio_spi_ps_ctrl,
                        uint32_t *gpio_spi_ps_data );

int socket_config_ad9508(   SchmidtCAM_Config *cfg, 
                            uint32_t *gpio_flt_ctrl, 
                            uint32_t *gpio_flt_data,
                            uint32_t *gpio_in,
                            uint32_t *gpio_pl_ps,
                            uint32_t *gpio_out,
                            uint32_t *gpio_out2,
                            uint32_t *gpio_spi_ps_ctrl,
                            uint32_t *gpio_spi_ps_data );

int socket_config_adc2reg_clk(  SchmidtCAM_Config *cfg, 
                                uint32_t *gpio_flt_ctrl, 
                                uint32_t *gpio_flt_data,
                                uint32_t *gpio_in,
                                uint32_t *gpio_pl_ps,
                                uint32_t *gpio_out,
                                uint32_t *gpio_out2,
                                uint32_t *gpio_spi_ps_ctrl,
                                uint32_t *gpio_spi_ps_data );

int socket_config_ads5294(  SchmidtCAM_Config *cfg, 
                            uint32_t *gpio_flt_ctrl, 
                            uint32_t *gpio_flt_data,
                            uint32_t *gpio_in,
                            uint32_t *gpio_pl_ps,
                            uint32_t *gpio_out,
                            uint32_t *gpio_out2,
                            uint32_t *gpio_spi_ps_ctrl,
                            uint32_t *gpio_spi_ps_data );

int socket_config_ccd_drive(SchmidtCAM_Config *cfg, 
                            uint32_t *gpio_flt_ctrl, 
                            uint32_t *gpio_flt_data,
                            uint32_t *gpio_in,
                            uint32_t *gpio_pl_ps,
                            uint32_t *gpio_out,
                            uint32_t *gpio_out2,
                            uint32_t *gpio_spi_ps_ctrl,
                            uint32_t *gpio_spi_ps_data );

int socket_config_daisy(SchmidtCAM_Config *cfg, 
                        uint32_t *gpio_flt_ctrl, 
                        uint32_t *gpio_flt_data,
                        uint32_t *gpio_in,
                        uint32_t *gpio_pl_ps,
                        uint32_t *gpio_out,
                        uint32_t *gpio_out2,
                        uint32_t *gpio_spi_ps_ctrl,
                        uint32_t *gpio_spi_ps_data,
                        int mode );

int socket_config_dacx0508( SchmidtCAM_Config *cfg, 
                            uint32_t *gpio_flt_ctrl, 
                            uint32_t *gpio_flt_data,
                            uint32_t *gpio_in,
                            uint32_t *gpio_pl_ps,
                            uint32_t *gpio_out,
                            uint32_t *gpio_out2,
                            uint32_t *gpio_spi_ps_ctrl,
                            uint32_t *gpio_spi_ps_data,
                            int mode );

int socket_config_dcds( SchmidtCAM_Config *cfg, 
                        uint32_t *gpio_flt_ctrl, 
                        uint32_t *gpio_flt_data,
                        uint32_t *gpio_in,
                        uint32_t *gpio_pl_ps,
                        uint32_t *gpio_out,
                        uint32_t *gpio_out2,
                        uint32_t *gpio_spi_ps_ctrl,
                        uint32_t *gpio_spi_ps_data );

int socket_power_down(  SchmidtCAM_Config *cfg, 
                        uint32_t *gpio_flt_ctrl, 
                        uint32_t *gpio_flt_data,
                        uint32_t *gpio_in,
                        uint32_t *gpio_pl_ps,
                        uint32_t *gpio_out,
                        uint32_t *gpio_out2,
                        uint32_t *gpio_spi_ps_ctrl,
                        uint32_t *gpio_spi_ps_data );

int socket_reset_ads5294(   SchmidtCAM_Config *cfg, 
                            uint32_t *gpio_flt_ctrl, 
                            uint32_t *gpio_flt_data,
                            uint32_t *gpio_in,
                            uint32_t *gpio_pl_ps,
                            uint32_t *gpio_out,
                            uint32_t *gpio_out2,
                            uint32_t *gpio_spi_ps_ctrl,
                            uint32_t *gpio_spi_ps_data);

int socket_sync_ads5294(    SchmidtCAM_Config *cfg, 
                            uint32_t *gpio_flt_ctrl, 
                            uint32_t *gpio_flt_data,
                            uint32_t *gpio_in,
                            uint32_t *gpio_pl_ps,
                            uint32_t *gpio_out,
                            uint32_t *gpio_out2,
                            uint32_t *gpio_spi_ps_ctrl,
                            uint32_t *gpio_spi_ps_data);

int socket_set_156MHz_clk(  SchmidtCAM_Config *cfg, 
                            uint32_t *gpio_flt_ctrl, 
                            uint32_t *gpio_flt_data,
                            uint32_t *gpio_in,
                            uint32_t *gpio_pl_ps,
                            uint32_t *gpio_out,
                            uint32_t *gpio_out2,
                            uint32_t *gpio_spi_ps_ctrl,
                            uint32_t *gpio_spi_ps_data, 
                            int opt );

int socket_set_afe( SchmidtCAM_Config *cfg, 
                    uint32_t *gpio_flt_ctrl, 
                    uint32_t *gpio_flt_data,
                    uint32_t *gpio_in,
                    uint32_t *gpio_pl_ps,
                    uint32_t *gpio_out,
                    uint32_t *gpio_out2,
                    uint32_t *gpio_spi_ps_ctrl,
                    uint32_t *gpio_spi_ps_data, 
                    int opt);

int socket_pinning( uint32_t *gpio_reg_ctrl, int opt );

int socket_set_wkdir();
int socket_open_log();
int socket_close_log();

// double time_diff(struct timeval *start, struct timeval *end);

#endif // _SCHMIDT_CAM_H_
